package com.gkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkd.context.BaseContext;
import com.gkd.mapper.*;
import com.gkd.pojo.dto.PostDTO;
import com.gkd.pojo.dto.PostPageQueryDTO;
import com.gkd.pojo.entity.*;
import com.gkd.pojo.vo.PostVO;
import com.gkd.pojo.vo.PublishListVO;
import com.gkd.result.PageResult;
import com.gkd.service.PostService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author ZJF
* @description 针对表【post】的数据库操作Service实现
* @createDate 2024-06-15 18:18:43
*/
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post>
    implements PostService{

    @Autowired
    private PostMapper postMapper;

    @Autowired
    private PostTagMapper postTagMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private LikesMapper likesMapper;

    /**
     * 文章上传
     * @param postDTO
     */
    @Transactional
    @Override
    public void add(PostDTO postDTO) {
        Post post = new Post();
        BeanUtils.copyProperties(postDTO,post);

        //获取作者id
        Integer userId = BaseContext.getCurrentId();
        post.setUserId(userId);
        //初始化浏览数
        post.setViews(0);

        //设置时间
        post.setCreateTime(new Date());
        post.setUpdateTime(new Date());

        //插入文章
        postMapper.insert(post);

        //插入文章标签关系
        List<String> tagNameList = postDTO.getTagName();
        if (tagNameList!=null&&tagNameList.size()>0){
            List<Tag> tagList = new ArrayList<>();

            //查找标签是否存在，不存在则插入标签
            tagNameList.forEach(tagName->{
                LambdaQueryWrapper<Tag> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(Tag::getTagName,tagName);
                Tag tag = tagMapper.selectOne(wrapper);
                if (tag==null){
                    tag=new Tag();
                    tag.setTagName(tagName);
                    tagMapper.insert(tag);
                }
                tagList.add(tag);
            });

            //插入文章标签关系
            List<PostTag> postTagList = new ArrayList<>();
            tagList.forEach(tag -> {
                PostTag postTag = PostTag.builder()
                        .postId(post.getPostId())
                        .tagId(tag.getTagId())
                        .build();
                postTagList.add(postTag);
            });
            postTagMapper.insertBatch(postTagList);
        }

    }

    /**
     * 文章分页查询
     * @param postPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(PostPageQueryDTO postPageQueryDTO) {
        Page<PostVO> page = new Page<>(postPageQueryDTO.getCurrent(), postPageQueryDTO.getPageSize());
        IPage<PostVO> postVOIPage =postMapper.selectPostsPage(page,postPageQueryDTO);

        List<PostVO> postVOList = postVOIPage.getRecords();

        //postVOList.forEach(postVO -> {
        //    Integer postId = postVO.getPostId();
        //    //通过postId在post_tag中获取tag_id列表
        //    LambdaQueryWrapper<PostTag> postTagWrapper = new LambdaQueryWrapper<>();
        //    postTagWrapper.eq(PostTag::getPostId,postId);
        //
        //    List<PostTag> postTagList = postTagMapper.selectList(postTagWrapper); //通过postId获取的postTag列表
        //
        //    List<Integer> tagIds = new ArrayList<>();//用来存储tagId
        //    //遍历列表获取tagId
        //    postTagList.forEach(postTag -> {
        //        Integer tagId = postTag.getTagId();
        //        tagIds.add(tagId);
        //    });
        //    if (tagIds.size()>0&&tagIds!=null){
        //        //通过tagIds查找对应的tagList
        //        List<Tag> tagList = tagMapper.selectBatchIds(tagIds);
        //
        //        //给postVO赋值
        //        postVO.setTagList(tagList);
        //    }
        //});

        //优化代码
        if (postVOList!=null&&postVOList.size()>0){
            // 1. 首先，从页面查询结果中提取所有唯一的 postId。
            Set<Integer> postIdsSet = new HashSet<>();
            postVOList.forEach(postVO -> {
                postIdsSet.add(postVO.getPostId());
            });

            // 2. 然后，使用 postIdsSet 一次性获取所有相关的 postTag 信息。
            LambdaQueryWrapper<PostTag> postTagWrapper = new LambdaQueryWrapper<>();
            postTagWrapper.in(PostTag::getPostId, postIdsSet);
            List<PostTag> postTagList = postTagMapper.selectList(postTagWrapper);

            // 3. 创建 postId 到 tagIds 的映射关系。
            Map<Integer, List<Integer>> postTagIdsMap = postTagList.stream()
                    .collect(Collectors.groupingBy(PostTag::getPostId, Collectors.mapping(PostTag::getTagId, Collectors.toList())));

            // 4. 从 postTagIdsMap 中提取所有 tagIds，以便进行批量查询。
            List<Integer> allTagIds = new ArrayList<>(postTagIdsMap.values()).stream()
                    .flatMap(Collection::stream)
                    .distinct()
                    .collect(Collectors.toList());

            if (allTagIds.size()>0&&allTagIds!=null){
                // 5. 批量获取所有 tagIds 对应的标签。
                List<Tag> allTags = tagMapper.selectBatchIds(allTagIds);

                // 6. 创建 tagId 到 Tag 对象的映射，以便快速检索。
                Map<Integer, Tag> tagMap = allTags.stream()
                        .collect(Collectors.toMap(Tag::getTagId, Function.identity()));

                // 7. 最后，遍历 PostVO 列表，为每个 PostVO 关联标签。
                postVOList.forEach(postVO -> {
                    Integer postId = postVO.getPostId();
                    // 根据 postId 获取对应的 tagIds 列表
                    List<Integer> tagIds = postTagIdsMap.getOrDefault(postId, Collections.emptyList());
                    // 根据 tagIds 获取对应的标签列表
                    List<Tag> tagList = tagIds.stream()
                            .map(tagMap::get)
                            .filter(Objects::nonNull) // 过滤掉可能不存在的标签
                            .collect(Collectors.toList());
                    // 给 postVO 赋值标签列表
                    postVO.setTagList(tagList);
                });
            }

        }

        return new PageResult(postVOIPage.getTotal(), postVOList);
    }

    /**
     * 修改文章
     * @param postDTO
     */
    @Transactional
    @Override
    public void update(PostDTO postDTO) {
        //更新文章
        Post post = new Post();
        BeanUtils.copyProperties(postDTO,post);
        post.setUpdateTime(new Date());
        postMapper.updateById(post);

        //更新标签
        //根据postId删除文章标签
        LambdaQueryWrapper<PostTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PostTag::getPostId,post.getPostId());
        postTagMapper.delete(wrapper);


        //插入文章标签关系
        List<String> tagNameList = postDTO.getTagName();
        if (tagNameList!=null&&tagNameList.size()>0){
            List<Tag> tagList = new ArrayList<>();

            //查找标签是否存在，不存在则插入标签
            tagNameList.forEach(tagName->{
                LambdaQueryWrapper<Tag> wrapperTag = new LambdaQueryWrapper<>();
                wrapperTag.eq(Tag::getTagName,tagName);
                Tag tag = tagMapper.selectOne(wrapperTag);
                if (tag==null){
                    tag=new Tag();
                    tag.setTagName(tagName);
                    tagMapper.insert(tag);
                }
                tagList.add(tag);
            });

            //插入文字标签关系
            List<PostTag> postTagList = new ArrayList<>();
            tagList.forEach(tag -> {
                PostTag postTag = PostTag.builder()
                        .postId(post.getPostId())
                        .tagId(tag.getTagId())
                        .build();
                postTagList.add(postTag);
            });
            postTagMapper.insertBatch(postTagList);
        }
    }

    /**
     * 根据id获取文章
     * @param postId
     * @return
     */
    @Override
    public PostVO getById(Integer postId) {
        //通过id查找post
        Post post = postMapper.selectById(postId);
        PostVO postVO = new PostVO();

        //将Post转换为PostVO
        BeanUtils.copyProperties(post,postVO);

        //获取用户名
        User user = userMapper.selectById(post.getUserId());
        postVO.setUsername(user.getUsername());

        //获取分类名
        Category category = categoryMapper.selectById(post.getCategoryId());
        postVO.setCategoryName(category.getCategoryName());

        //获取标签列表
        LambdaQueryWrapper<PostTag> wrapper = new LambdaQueryWrapper<>();
        //通过postId查找postTag
        wrapper.eq(PostTag::getPostId,post.getPostId());
        List<PostTag> postTagList = postTagMapper.selectList(wrapper);

        //通过tagId查找对应tag
        List<Tag> tagList = new ArrayList<>();
        if (postTagList!=null&&postTagList.size()>0){
            postTagList.forEach(postTag -> {
                Tag tag = tagMapper.selectById(postTag.getTagId());
                tagList.add(tag);
            });
        }
        postVO.setTagList(tagList);

        //添加浏览量
        post.setViews(post.getViews()+1);
        postMapper.updateById(post);

        return postVO;
    }

    /**
     * 删除文章和关联的文章标签、点赞和收藏
     * @param postIds
     */
    @Transactional
    @Override
    public void deleteByIds(List<Integer> postIds) {
        //删除文章
        postMapper.deleteBatchIds(postIds);
        //删除与文章关联的文章标签
        postIds.forEach(postId->{
            LambdaQueryWrapper<PostTag> postTagWrapper = new LambdaQueryWrapper<>();
            postTagWrapper.eq(PostTag::getPostId,postId);
            postTagMapper.delete(postTagWrapper);
        });

        //删除该文章下的收藏
        postIds.forEach(postId->{
            LambdaQueryWrapper<Favorite> favoriteWrapper = new LambdaQueryWrapper<>();
            favoriteWrapper.eq(Favorite::getPostId,postId);
            favoriteMapper.delete(favoriteWrapper);
        });

        //删除该文章下的点赞
        postIds.forEach(postId->{
            LambdaQueryWrapper<Likes> likesWrapper = new LambdaQueryWrapper<>();
            likesWrapper.eq(Likes::getPostId,postId);
            likesMapper.delete(likesWrapper);
        });

    }

    /**
     * 总浏览量
     * @return
     */
    @Override
    public Long sumView() {
        return postMapper.sumView();
    }

    /**
     * 获取近七天的发布数量
     * @return
     */
    @Override
    public List<PublishListVO> publishList() {

        Date endDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);

        Integer interval =-7;

        //计算七天前的时间
        calendar.add(Calendar.DATE,interval);
        Date startDate=calendar.getTime();

        return postMapper.countPostsByDayInRange(startDate,endDate);
    }

    /**
     * 文章分类统计
     * @return
     */
    @Override
    public List<Map<String, Object>> selectCategoryPostCounts() {
        // 直接委托给MyBatis的mapper代理对象
        return postMapper.selectCategoryPostCounts();
    }

}




